/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.ujf.sharepas.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import edu.ujf.sharepas.impl.Constante.UserState;
import java.util.Observable;

import org.eclipse.swt.widgets.Display;

import edu.ujf.sharepas.impl.Constante.CategoryType;
import edu.ujf.sharepas.impl.Constante.Right;
import edu.ujf.sharepas.impl.Constante.UserState;
import edu.ujf.sharepas.rmi.Client;

/**
 * 
 * @author yaiba
 */
public class User extends Observable implements Serializable{


	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String name;

	private int id;

	private String avatar;

	private Library userLib;
	
	protected String libFilePath = null;
	//
	private String message = null;

	// state of user (connected,busy, disconnected...)
	private Constante.UserState state = null;

	private Client client;

	// list of friends
	private List<User> friends;
   
    public User(Client c,int id,String name, String av, String message){
        this.id = id;
    	this.name =  name;
        if(avatar != null){
            this.avatar = av;
            }else{
            	this.avatar  = null;
            }
        this.message = message;
        this.userLib = new Library(this);
        this.client = c;
        this.friends = new ArrayList<User>();

    }

    
    public Client getClient(){
    	return this.client;
    	
    }
    
	public void setId(int id){
		this.id = id;
	}
	
	public int getId(){
		return this.id;
	}



    public User(Client c) {
    	this.id = Integer.parseInt(Constante.getSharePasProperty(Constante.Property.ID.toString()));
    	this.name = Constante.getSharePasProperty(Constante.Property.DEFAULT_USER.toString()) ;
    	this.libFilePath = Constante.getSharePasProperty(Constante.Property.USERLIB.toString()) ;
    	this.avatar = Constante.getSharePasProperty(Constante.Property.AVATAR.toString());
	
        this.message = Constante.getSharePasProperty(Constante.Property.MESSAGE.toString());

        this.userLib = Parser.getLibrary(this);
        this.userLib.setOwner(this);
        this.client = c;
        this.friends = new ArrayList<User>();
      	this.getFriends(Constante.getSharePasProperty(Constante.Property.FRIEND_PATH.toString()));
      	setChanged();
      	
    }
    
    public String getLibFilePath(){
    	return this.libFilePath;
    }
    
    /**
     * foncton permettant de recuperer un fichier situe chez un utilisateur
     * @param u
     * @param FileNames
     * @return
     */
    public ShareFile getShareFile(String FileName){
    	return null;
    }
    
   
    private void getFriends(String DirPath){
    	File dir = new File(DirPath);
    	Friend userCurrent = null;
    	Library currentLib = null;
    	System.out.println(dir.getAbsolutePath());
    	if(dir!=null && dir.exists() && dir.isDirectory()){
    		for(File f:dir.listFiles()){
    			String userName = f.getName().split(".lib")[0];
    			int id = 0;
    			try {
					BufferedReader reader = new BufferedReader(new FileReader(f));
					id = Integer.parseInt(reader.readLine());
    			} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
    			userCurrent = new Friend(null,0,userName,null,null);
    			userCurrent.setId(id);
    			userCurrent.setState(UserState.DISCONNECTED);
    			this.friends.add(userCurrent);
        		currentLib = Parser.getLibrary(userCurrent);	
        		userCurrent.setUserLib(currentLib);
    		}
    		
    	}
    }

	
	
    public User(Client c, String name) throws RemoteException{

    	this.name = name ;
    	this.avatar = null;
        this.message = "default";
        this.userLib = Parser.getLibrary(this);
        this.client = c;
        this.friends = new ArrayList<User>();
    }
    
    public User(Client c,String name, String av, String message,File library) throws RemoteException{
        this.name = name;
        if(avatar != null){
        this.avatar = av;
        }else{
        	this.avatar  = null;
        }
        this.message = message;
        this.userLib = Parser.getLibrary(this);
        this.friends = new ArrayList<User>();


    }
    
   

	public UserState getState() {
		return this.state;
	}

	
	public void setClient(Client c ){
		this.client = c;
	}
	public void updateFriends(List<User> list) {
		
		friends.clear();
		System.out.println("update Friends");
		for(User u:list){
			System.out.println("user : "+u.getName());
			if( !u.equals(this) ){
				if( u instanceof Friend ){
					friends.add(u);
				}else{
					User us = new Friend(u.getClient(),u.getId(),u.getName(),u.getAvatar(),u.getMessage()); 
					us.setState(u.getState());
					us.setUserLib(u.getUserLib());
					friends.add(us);
				}
			}
		}
		
		for(User u:friends){
			System.out.println("user this "+this.getName());
			System.out.println("user name "+u.getName());
				Parser.Save(u.getUserLib());
		}
		setChanged();	
		notifyObservers();
	
	}

	public String getMessage(){
		return this.message;
	}
	public String getAvatar(){
		return this.avatar;
	}
	/**
	 * return library of the user specified in parameter
	 * 
	 * @param user
	 */
	public static Library getLibrary(User user) {
		return user.getUserLib();
	}

	/**
	 * return list of library known
	 * 
	 * @return
	 */
	public List<Library> getListLibrary() {
		List<Library> lib = new ArrayList<Library>();
		File dirFriends = new File(Constante
				.getSharePasProperty(Constante.Property.FRIEND_PATH.toString()));
		for (File f : dirFriends.listFiles()) {
			lib.add(Parser.getLibrary(this,f.getAbsolutePath()));
		}
		return lib;
	}

	
	public void setMessage(String messge){
		this.message = messge;
	}
	
	public void setAvatar(String avatar){
		this.avatar = avatar;
	}
	/**
	 * add a new file to a category of user library
	 * 
	 * @param filePath
	 * @param category
	 */
	public void addFile(String filePath, Category category) {
		ShareFile f = new ShareFile(filePath, Right.READ);
		category.addShareFile(f);
		Parser.Save(this.getUserLib());
		setChanged();
		notifyObservers();
	}

	
	public void addFile(String filePath) {
		CategoryType category = null;
		if( filePath.endsWith(".avi") ){
			category = CategoryType.VIDEO;
		}else if( filePath.endsWith(".mp3") ){
			category = CategoryType.AUDIO;
		}else if( filePath.endsWith(".doc") ){
			category = CategoryType.DOC;
		}else if( filePath.endsWith(".jpg")){
			category = CategoryType.PHOTO;
		}
		Category c = this.userLib.getCategory(category);
		ShareFile f = new ShareFile(filePath, Right.READ);
		c.addShareFile(f);
		Parser.Save(this.userLib);
		try {
			this.client.getServeur().updateUser(this.client);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		setChanged();
		notifyObservers();
	}
	
	public void addFile(String filePath, Constante.CategoryType category) {
		Category c = this.userLib.getCategory(category);
		ShareFile f = new ShareFile(filePath, Right.READ);
		c.addShareFile(f);
		Parser.Save(this.userLib);
		setChanged();
		notifyObservers();
	}

	public void addFile(String filePath, Category category, Right right) {
		ShareFile f = new ShareFile(filePath, right);
		category.addShareFile(f);
		Parser.Save(this.getUserLib());
		setChanged();
		notifyObservers();

	}

	/**
	 * add a new diectory to a category of user library
	 * 
	 * @param directoryPath
	 * @param category
	 */
	public void addDirectory(String directoryPath, Category category) {
		File fl = new File(directoryPath);
		for (File f : fl.listFiles()) {
			category
					.addShareFile(new ShareFile(f.getAbsolutePath(), Right.READ));
		}
		Parser.Save(this.getUserLib());

		setChanged();
		notifyObservers();
	}

	public void addDirectory(String directoryPath, Constante.CategoryType type) {
		Category c = this.userLib.getCategory(type);
		File fl = new File(directoryPath);
		for (File f : fl.listFiles()) {
			c.addShareFile(new ShareFile(f.getAbsolutePath(), Right.READ));
		}
		Parser.Save(this.getUserLib());

		setChanged();
		notifyObservers();

	}

	/**
	 * return list of ShareFile that correspond to categories specified and
	 * regular expression
	 * 
	 * @param category
	 * @param name
	 * @return
	 */
	public List<ShareFile> getShareFile(List<Category> category, String regExp) {
		return null;
	}

	/**
	 * 
	 * @param f
	 * @return
	 */
	
	public boolean equals(Object u){
		if( u instanceof User ){
			return ((User)u).getId() == this.getId();
		}else
			return false;

	}

	public int deleteFile(ShareFile f) {
		return 0;
	}

	public int deleteDirectory(ShareFile d) {
		return 0;
	}

	/**
	 * save all user information , library ...
	 */
	public void saveUser() {
		Parser.Save(this.userLib);
	}

	public void setUserLib(Library userLib) {
		this.userLib = userLib;
		userLib.setOwner(this);
	}

	
	public Library getUserLib() {
		return userLib;
	}


	public void setState(UserState userState) {
		this.state = userState ;
		setChanged();
		notifyObservers();
	}
	
	public boolean isConnected(){
		return this.state == UserState.CONNECTED ? true : false ;
		
	}

	public List<User> getFriends() {
		return friends;
	}

	
	public void addFriends(Friend u) {
		friends.add(u);
		setChanged();
	}
	
	public void removeFriends(User u) {
		friends.remove(u);
		setChanged();
	}


	public String getName() {

		return this.name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public boolean isBusy() {
		return state == UserState.BUSY ? true : false ;
	}

}
